home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / x / twm93053.lha / twm / resize.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  35.6 KB  |  1,190 lines

  1. /*****************************************************************************/
  2. /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  3. /**                          Salt Lake City, Utah                           **/
  4. /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
  5. /**                        Cambridge, Massachusetts                         **/
  6. /**                                                                         **/
  7. /**                           All Rights Reserved                           **/
  8. /**                                                                         **/
  9. /**    Permission to use, copy, modify, and distribute this software and    **/
  10. /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  11. /**    granted, provided that the above copyright notice appear  in  all    **/
  12. /**    copies and that both  that  copyright  notice  and  this  permis-    **/
  13. /**    sion  notice appear in supporting  documentation,  and  that  the    **/
  14. /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
  15. /**    in publicity pertaining to distribution of the  software  without    **/
  16. /**    specific, written prior permission.                                  **/
  17. /**                                                                         **/
  18. /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
  19. /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
  20. /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
  21. /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
  22. /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
  23. /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
  24. /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
  25. /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
  26. /*****************************************************************************/
  27.  
  28.  
  29. /***********************************************************************
  30.  *
  31.  * $XConsortium: resize.c,v 1.80 91/05/11 17:35:42 dave Exp $
  32.  *
  33.  * window resizing borrowed from the "wm" window manager
  34.  *
  35.  * 11-Dec-87 Thomas E. LaStrange                File created
  36.  *
  37.  ***********************************************************************/
  38.  
  39. #include <stdio.h>
  40. #include "twm.h"
  41. #include "parse.h"
  42. #include "util.h"
  43. #include "resize.h"
  44. #include "add_window.h"
  45. #include "screen.h"
  46.  
  47. #define MINHEIGHT 0     /* had been 32 */
  48. #define MINWIDTH 0      /* had been 60 */
  49.  
  50. static int dragx;       /* all these variables are used */
  51. static int dragy;       /* in resize operations */
  52. static int dragWidth;
  53. static int dragHeight;
  54.  
  55. static int origx;
  56. static int origy;
  57. static int origWidth;
  58. static int origHeight;
  59.  
  60. static int clampTop;
  61. static int clampBottom;
  62. static int clampLeft;
  63. static int clampRight;
  64. static int clampDX;
  65. static int clampDY;
  66.  
  67. static int last_width;
  68. static int last_height;
  69.  
  70.  
  71. static void do_auto_clamp (tmp_win, evp)
  72.     TwmWindow *tmp_win;
  73.     XEvent *evp;
  74. {
  75.     Window junkRoot;
  76.     int x, y, h, v, junkbw;
  77.     unsigned int junkMask;
  78.  
  79.     switch (evp->type) {
  80.       case ButtonPress:
  81.     x = evp->xbutton.x_root;
  82.     y = evp->xbutton.y_root;
  83.     break;
  84.       case KeyPress:
  85.     x = evp->xkey.x_root;
  86.     y = evp->xkey.y_root;
  87.     break;
  88.       default:
  89.     if (!XQueryPointer (dpy, Scr->Root, &junkRoot, &junkRoot,
  90.                 &x, &y, &junkbw, &junkbw, &junkMask))
  91.       return;
  92.     }
  93.  
  94.     h = ((x - dragx) / (dragWidth < 3 ? 1 : (dragWidth / 3)));
  95.     v = ((y - dragy - tmp_win->title_height) / 
  96.      (dragHeight < 3 ? 1 : (dragHeight / 3)));
  97.     
  98.     if (h <= 0) {
  99.     clampLeft = 1;
  100.     clampDX = (x - dragx);
  101.     } else if (h >= 2) {
  102.     clampRight = 1;
  103.     clampDX = (x - dragx - dragWidth);
  104.     }
  105.  
  106.     if (v <= 0) {
  107.     clampTop = 1;
  108.     clampDY = (y - dragy);
  109.     } else if (v >= 2) {
  110.     clampBottom = 1;
  111.     clampDY = (y - dragy - dragHeight);
  112.     }
  113. }
  114.  
  115.  
  116. /***********************************************************************
  117.  *
  118.  *  Procedure:
  119.  *      StartResize - begin a window resize operation
  120.  *
  121.  *  Inputs:
  122.  *      ev      - the event structure (button press)
  123.  *      tmp_win - the TwmWindow pointer
  124.  *      fromtitlebar - action invoked from titlebar button
  125.  *
  126.  ***********************************************************************
  127.  */
  128.  
  129. void
  130. StartResize(evp, tmp_win, fromtitlebar)
  131. XEvent *evp;
  132. TwmWindow *tmp_win;
  133. Bool fromtitlebar;
  134. {
  135.     Window      junkRoot;
  136.     unsigned int junkbw, junkDepth;
  137.  
  138.     ResizeWindow = tmp_win->frame;
  139.     XGrabServer(dpy);
  140.     XGrabPointer(dpy, Scr->Root, True,
  141.         ButtonPressMask | ButtonReleaseMask |
  142.     ButtonMotionMask | PointerMotionHintMask,
  143.         GrabModeAsync, GrabModeAsync,
  144.         Scr->Root, Scr->ResizeCursor, CurrentTime);
  145.  
  146.     XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
  147.         &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, &junkbw,
  148.                  &junkDepth);
  149.     dragx += tmp_win->frame_bw;
  150.     dragy += tmp_win->frame_bw;
  151.     origx = dragx;
  152.     origy = dragy;
  153.     origWidth = dragWidth;
  154.     origHeight = dragHeight;
  155.     clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0;
  156.  
  157.     if (Scr->AutoRelativeResize && !fromtitlebar)
  158.       do_auto_clamp (tmp_win, evp);
  159.  
  160.     Scr->SizeStringOffset = SIZE_HINDENT;
  161.     XResizeWindow (dpy, Scr->SizeWindow,
  162.            Scr->SizeStringWidth + SIZE_HINDENT * 2, 
  163.            Scr->SizeFont.height + SIZE_VINDENT * 2);
  164.     XMapRaised(dpy, Scr->SizeWindow);
  165.     InstallRootColormap();
  166.     last_width = 0;
  167.     last_height = 0;
  168.     DisplaySize(tmp_win, origWidth, origHeight);
  169.     MoveOutline (Scr->Root, dragx - tmp_win->frame_bw,
  170.          dragy - tmp_win->frame_bw, dragWidth + 2 * tmp_win->frame_bw,
  171.          dragHeight + 2 * tmp_win->frame_bw,
  172.          tmp_win->frame_bw, tmp_win->title_height);
  173. }
  174.  
  175.  
  176.  
  177. void
  178. MenuStartResize(tmp_win, x, y, w, h)
  179. TwmWindow *tmp_win;
  180. int x, y, w, h;
  181. {
  182.   Window junkRoot;
  183.   unsigned int junkbw, junkDepth;
  184.     XGrabServer(dpy);
  185.     XGrabPointer(dpy, Scr->Root, True,
  186.         ButtonPressMask | ButtonMotionMask | PointerMotionMask,
  187.         GrabModeAsync, GrabModeAsync,
  188.         Scr->Root, Scr->ResizeCursor, CurrentTime);
  189.     dragx = x + tmp_win->frame_bw;
  190.     dragy = y + tmp_win->frame_bw;
  191.     origx = dragx;
  192.     origy = dragy;
  193.     dragWidth = origWidth = w; /* - 2 * tmp_win->frame_bw; */
  194.     dragHeight = origHeight = h; /* - 2 * tmp_win->frame_bw; */
  195.     clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0;
  196.     last_width = 0;
  197.     last_height = 0;
  198.     Scr->SizeStringOffset = SIZE_HINDENT;
  199.     XResizeWindow (dpy, Scr->SizeWindow,
  200.            Scr->SizeStringWidth + SIZE_HINDENT * 2, 
  201.            Scr->SizeFont.height + SIZE_VINDENT * 2);
  202.     XMapRaised(dpy, Scr->SizeWindow);
  203.     DisplaySize(tmp_win, origWidth, origHeight);
  204.     MoveOutline (Scr->Root, dragx - tmp_win->frame_bw,
  205.          dragy - tmp_win->frame_bw, 
  206.          dragWidth + 2 * tmp_win->frame_bw,
  207.          dragHeight + 2 * tmp_win->frame_bw,
  208.          tmp_win->frame_bw, tmp_win->title_height);
  209. }
  210.  
  211. /***********************************************************************
  212.  *
  213.  *  Procedure:
  214.  *      AddStartResize - begin a windorew resize operation from AddWindow
  215.  *
  216.  *  Inputs:
  217.  *      tmp_win - the TwmWindow pointer
  218.  *
  219.  ***********************************************************************
  220.  */
  221.  
  222. void
  223. AddStartResize(tmp_win, x, y, w, h)
  224. TwmWindow *tmp_win;
  225. int x, y, w, h;
  226. {
  227.     XGrabServer(dpy);
  228.     XGrabPointer(dpy, Scr->Root, True,
  229.         ButtonReleaseMask | ButtonMotionMask | PointerMotionHintMask,
  230.         GrabModeAsync, GrabModeAsync,
  231.         Scr->Root, Scr->ResizeCursor, CurrentTime);
  232.  
  233.     dragx = x + tmp_win->frame_bw;
  234.     dragy = y + tmp_win->frame_bw;
  235.     origx = dragx;
  236.     origy = dragy;
  237.     dragWidth = origWidth = w - 2 * tmp_win->frame_bw;
  238.     dragHeight = origHeight = h - 2 * tmp_win->frame_bw;
  239.     clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0;
  240. /*****
  241.     if (Scr->AutoRelativeResize) {
  242.     clampRight = clampBottom = 1;
  243.     }
  244. *****/
  245.     last_width = 0;
  246.     last_height = 0;
  247.     DisplaySize(tmp_win, origWidth, origHeight);
  248. }
  249.  
  250.  
  251.  
  252. void
  253. MenuDoResize(x_root, y_root, tmp_win)
  254. int x_root;
  255. int y_root;
  256. TwmWindow *tmp_win;
  257. {
  258.     int action;
  259.  
  260.     action = 0;
  261.  
  262.     x_root -= clampDX;
  263.     y_root -= clampDY;
  264.  
  265.     if (clampTop) {
  266.         int         delta = y_root - dragy;
  267.         if (dragHeight - delta < MINHEIGHT) {
  268.             delta = dragHeight - MINHEIGHT;
  269.             clampTop = 0;
  270.         }
  271.         dragy += delta;
  272.         dragHeight -= delta;
  273.         action = 1;
  274.     }
  275.     else if (y_root <= dragy/* ||
  276.              y_root == findRootInfo(root)->rooty*/) {
  277.         dragy = y_root;
  278.         dragHeight = origy + origHeight -
  279.             y_root;
  280.         clampBottom = 0;
  281.         clampTop = 1;
  282.     clampDY = 0;
  283.         action = 1;
  284.     }
  285.     if (clampLeft) {
  286.         int         delta = x_root - dragx;
  287.         if (dragWidth - delta < MINWIDTH) {
  288.             delta = dragWidth - MINWIDTH;
  289.             clampLeft = 0;
  290.         }
  291.         dragx += delta;
  292.         dragWidth -= delta;
  293.         action = 1;
  294.     }
  295.     else if (x_root <= dragx/* ||
  296.              x_root == findRootInfo(root)->rootx*/) {
  297.         dragx = x_root;
  298.         dragWidth = origx + origWidth -
  299.             x_root;
  300.         clampRight = 0;
  301.         clampLeft = 1;
  302.     clampDX = 0;
  303.         action = 1;
  304.     }
  305.     if (clampBottom) {
  306.         int         delta = y_root - dragy - dragHeight;
  307.         if (dragHeight + delta < MINHEIGHT) {
  308.             delta = MINHEIGHT - dragHeight;
  309.             clampBottom = 0;
  310.         }
  311.         dragHeight += delta;
  312.         action = 1;
  313.     }
  314.     else if (y_root >= dragy + dragHeight) {
  315.         dragy = origy;
  316.         dragHeight = 1 + y_root - dragy;
  317.         clampTop = 0;
  318.         clampBottom = 1;
  319.     clampDY = 0;
  320.         action = 1;
  321.     }
  322.     if (clampRight) {
  323.         int         delta = x_root - dragx - dragWidth;
  324.         if (dragWidth + delta < MINWIDTH) {
  325.             delta = MINWIDTH - dragWidth;
  326.             clampRight = 0;
  327.         }
  328.         dragWidth += delta;
  329.         action = 1;
  330.     }
  331.     else if (x_root >= dragx + dragWidth) {
  332.         dragx = origx;
  333.         dragWidth = 1 + x_root - origx;
  334.         clampLeft = 0;
  335.         clampRight = 1;
  336.     clampDX = 0;
  337.         action = 1;
  338.     }
  339.  
  340.     if (action) {
  341.         ConstrainSize (tmp_win, &dragWidth, &dragHeight);
  342.         if (clampLeft)
  343.             dragx = origx + origWidth - dragWidth;
  344.         if (clampTop)
  345.             dragy = origy + origHeight - dragHeight;
  346.         MoveOutline(Scr->Root,
  347.             dragx - tmp_win->frame_bw,
  348.             dragy - tmp_win->frame_bw,
  349.             dragWidth + 2 * tmp_win->frame_bw,
  350.             dragHeight + 2 * tmp_win->frame_bw,
  351.         tmp_win->frame_bw, tmp_win->title_height);
  352.     }
  353.  
  354.     DisplaySize(tmp_win, dragWidth, dragHeight);
  355. }
  356.  
  357. /***********************************************************************
  358.  *
  359.  *  Procedure:
  360.  *      DoResize - move the rubberband around.  This is called for
  361.  *                 each motion event when we are resizing
  362.  *
  363.  *  Inputs:
  364.  *      x_root  - the X corrdinate in the root window
  365.  *      y_root  - the Y corrdinate in the root window
  366.  *      tmp_win - the current twm window
  367.  *
  368.  ***********************************************************************
  369.  */
  370.  
  371. void
  372. DoResize(x_root, y_root, tmp_win)
  373. int x_root;
  374. int y_root;
  375. TwmWindow *tmp_win;
  376. {
  377.     int action;
  378.  
  379.     action = 0;
  380.  
  381.     x_root -= clampDX;
  382.     y_root -= clampDY;
  383.  
  384.     if (clampTop) {
  385.         int         delta = y_root - dragy;
  386.         if (dragHeight - delta < MINHEIGHT) {
  387.             delta = dragHeight - MINHEIGHT;
  388.             clampTop = 0;
  389.         }
  390.         dragy += delta;
  391.         dragHeight -= delta;
  392.         action = 1;
  393.     }
  394.     else if (y_root <= dragy/* ||
  395.              y_root == findRootInfo(root)->rooty*/) {
  396.         dragy = y_root;
  397.         dragHeight = origy + origHeight -
  398.             y_root;
  399.         clampBottom = 0;
  400.         clampTop = 1;
  401.     clampDY = 0;
  402.         action = 1;
  403.     }
  404.     if (clampLeft) {
  405.         int         delta = x_root - dragx;
  406.         if (dragWidth - delta < MINWIDTH) {
  407.             delta = dragWidth - MINWIDTH;
  408.             clampLeft = 0;
  409.         }
  410.         dragx += delta;
  411.         dragWidth -= delta;
  412.         action = 1;
  413.     }
  414.     else if (x_root <= dragx/* ||
  415.              x_root == findRootInfo(root)->rootx*/) {
  416.         dragx = x_root;
  417.         dragWidth = origx + origWidth -
  418.             x_root;
  419.         clampRight = 0;
  420.         clampLeft = 1;
  421.     clampDX = 0;
  422.         action = 1;
  423.     }
  424.     if (clampBottom) {
  425.         int         delta = y_root - dragy - dragHeight;
  426.         if (dragHeight + delta < MINHEIGHT) {
  427.             delta = MINHEIGHT - dragHeight;
  428.             clampBottom = 0;
  429.         }
  430.         dragHeight += delta;
  431.         action = 1;
  432.     }
  433.     else if (y_root >= dragy + dragHeight - 1/* ||
  434.            y_root == findRootInfo(root)->rooty
  435.            + findRootInfo(root)->rootheight - 1*/) {
  436.         dragy = origy;
  437.         dragHeight = 1 + y_root - dragy;
  438.         clampTop = 0;
  439.         clampBottom = 1;
  440.     clampDY = 0;
  441.         action = 1;
  442.     }
  443.     if (clampRight) {
  444.         int         delta = x_root - dragx - dragWidth;
  445.         if (dragWidth + delta < MINWIDTH) {
  446.             delta = MINWIDTH - dragWidth;
  447.             clampRight = 0;
  448.         }
  449.         dragWidth += delta;
  450.         action = 1;
  451.     }
  452.     else if (x_root >= dragx + dragWidth - 1/* ||
  453.              x_root == findRootInfo(root)->rootx +
  454.              findRootInfo(root)->rootwidth - 1*/) {
  455.         dragx = origx;
  456.         dragWidth = 1 + x_root - origx;
  457.         clampLeft = 0;
  458.         clampRight = 1;
  459.     clampDX = 0;
  460.         action = 1;
  461.     }
  462.  
  463.     if (action) {
  464.         ConstrainSize (tmp_win, &dragWidth, &dragHeight);
  465.         if (clampLeft)
  466.             dragx = origx + origWidth - dragWidth;
  467.         if (clampTop)
  468.             dragy = origy + origHeight - dragHeight;
  469.         MoveOutline(Scr->Root,
  470.             dragx - tmp_win->frame_bw,
  471.             dragy - tmp_win->frame_bw,
  472.             dragWidth + 2 * tmp_win->frame_bw,
  473.             dragHeight + 2 * tmp_win->frame_bw,
  474.         tmp_win->frame_bw, tmp_win->title_height);
  475.     }
  476.  
  477.     DisplaySize(tmp_win, dragWidth, dragHeight);
  478. }
  479.  
  480. /***********************************************************************
  481.  *
  482.  *  Procedure:
  483.  *      DisplaySize - display the size in the dimensions window
  484.  *
  485.  *  Inputs:
  486.  *      tmp_win - the current twm window
  487.  *      width   - the width of the rubber band
  488.  *      height  - the height of the rubber band
  489.  *
  490.  ***********************************************************************
  491.  */
  492.  
  493. void
  494. DisplaySize(tmp_win, width, height)
  495. TwmWindow *tmp_win;
  496. int width;
  497. int height;
  498. {
  499.     char str[100];
  500.     int dwidth;
  501.     int dheight;
  502.  
  503.     if (last_width == width && last_height == height)
  504.         return;
  505.  
  506.     last_width = width;
  507.     last_height = height;
  508.  
  509.     dheight = height - tmp_win->title_height;
  510.     dwidth = width;
  511.  
  512.     /*
  513.      * ICCCM says that PMinSize is the default is no PBaseSize is given,
  514.      * and vice-versa.
  515.      */
  516.     if (tmp_win->hints.flags&(PMinSize|PBaseSize) && tmp_win->hints.flags & PResizeInc)
  517.     {
  518.     if (tmp_win->hints.flags & PBaseSize) {
  519.         dwidth -= tmp_win->hints.base_width;
  520.         dheight -= tmp_win->hints.base_height;
  521.     } else {
  522.         dwidth -= tmp_win->hints.min_width;
  523.         dheight -= tmp_win->hints.min_height;
  524.     }
  525.     }
  526.  
  527.     if (tmp_win->hints.flags & PResizeInc)
  528.     {
  529.         dwidth /= tmp_win->hints.width_inc;
  530.         dheight /= tmp_win->hints.height_inc;
  531.     }
  532.  
  533.     (void) sprintf (str, " %4d x %-4d ", dwidth, dheight);
  534.     XRaiseWindow(dpy, Scr->SizeWindow);
  535.     FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont.font->fid);
  536.     XDrawImageString (dpy, Scr->SizeWindow, Scr->NormalGC,
  537.               Scr->SizeStringOffset,
  538.               Scr->SizeFont.font->ascent + SIZE_VINDENT,
  539.               str, 13);
  540. }
  541.  
  542. /***********************************************************************
  543.  *
  544.  *  Procedure:
  545.  *      EndResize - finish the resize operation
  546.  *
  547.  ***********************************************************************
  548.  */
  549.  
  550. void
  551. EndResize()
  552. {
  553.     TwmWindow *tmp_win;
  554.  
  555. #ifdef DEBUG
  556.     fprintf(stderr, "EndResize\n");
  557. #endif
  558.  
  559.     MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
  560.     XUnmapWindow(dpy, Scr->SizeWindow);
  561.  
  562.     XFindContext(dpy, ResizeWindow, TwmContext, (caddr_t *)&tmp_win);
  563.  
  564.     ConstrainSize (tmp_win, &dragWidth, &dragHeight);
  565.  
  566.     if (dragWidth != tmp_win->frame_width ||
  567.         dragHeight != tmp_win->frame_height)
  568.             tmp_win->zoomed = ZOOM_NONE;
  569.  
  570.     SetupWindow (tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw,
  571.          dragWidth, dragHeight, -1);
  572.  
  573.     if (tmp_win->iconmgr)
  574.     {
  575.     int ncols = tmp_win->iconmgrp->cur_columns;
  576.     if (ncols == 0) ncols = 1;
  577.  
  578.     tmp_win->iconmgrp->width = (int) ((dragWidth *
  579.                        (long) tmp_win->iconmgrp->columns)
  580.                       / ncols);
  581.         PackIconManager(tmp_win->iconmgrp);
  582.     }
  583.  
  584.     if (!Scr->NoRaiseResize)
  585.         XRaiseWindow(dpy, tmp_win->frame);
  586.  
  587.     UninstallRootColormap();
  588.  
  589.     ResizeWindow = None;
  590. }
  591.  
  592. void
  593. MenuEndResize(tmp_win)
  594. TwmWindow *tmp_win;
  595. {
  596.     MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
  597.     XUnmapWindow(dpy, Scr->SizeWindow);
  598.     ConstrainSize (tmp_win, &dragWidth, &dragHeight);
  599.     AddingX = dragx;
  600.     AddingY = dragy;
  601.     AddingW = dragWidth + (2 * tmp_win->frame_bw);
  602.     AddingH = dragHeight + (2 * tmp_win->frame_bw);
  603.     SetupWindow (tmp_win, AddingX, AddingY, AddingW, AddingH, -1);
  604. }
  605.  
  606.  
  607.  
  608. /***********************************************************************
  609.  *
  610.  *  Procedure:
  611.  *      AddEndResize - finish the resize operation for AddWindo<w
  612.  *
  613.  ***********************************************************************
  614.  */
  615.  
  616. void
  617. AddEndResize(tmp_win)
  618. TwmWindow *tmp_win;
  619. {
  620.  
  621. #ifdef DEBUG
  622.     fprintf(stderr, "AddEndResize\n");
  623. #endif
  624.  
  625.     ConstrainSize (tmp_win, &dragWidth, &dragHeight);
  626.     AddingX = dragx;
  627.     AddingY = dragy;
  628.     AddingW = dragWidth + (2 * tmp_win->frame_bw);
  629.     AddingH = dragHeight + (2 * tmp_win->frame_bw);
  630. }
  631.  
  632. /***********************************************************************
  633.  *
  634.  *  Procedure:
  635.  *      ConstrainSize - adjust the given width and height to account for the
  636.  *              constraints imposed by size hints
  637.  *
  638.  *      The general algorithm, especially the aspect ratio stuff, is
  639.  *      borrowed from uwm's CheckConsistency routine.
  640.  * 
  641.  ***********************************************************************/
  642.  
  643. ConstrainSize (tmp_win, widthp, heightp)
  644.     TwmWindow *tmp_win;
  645.     int *widthp, *heightp;
  646. {
  647. #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
  648. #define _min(a,b) (((a) < (b)) ? (a) : (b))
  649.  
  650.     int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
  651.     int baseWidth, baseHeight;
  652.     int dwidth = *widthp, dheight = *heightp;
  653.  
  654.  
  655.     dheight -= tmp_win->title_height;
  656.  
  657.     if (tmp_win->hints.flags & PMinSize) {
  658.         minWidth = tmp_win->hints.min_width;
  659.         minHeight = tmp_win->hints.min_height;
  660.     } else if (tmp_win->hints.flags & PBaseSize) {
  661.         minWidth = tmp_win->hints.base_width;
  662.         minHeight = tmp_win->hints.base_height;
  663.     } else
  664.         minWidth = minHeight = 1;
  665.  
  666.     if (tmp_win->hints.flags & PBaseSize) {
  667.     baseWidth = tmp_win->hints.base_width;
  668.     baseHeight = tmp_win->hints.base_height;
  669.     } else if (tmp_win->hints.flags & PMinSize) {
  670.     baseWidth = tmp_win->hints.min_width;
  671.     baseHeight = tmp_win->hints.min_height;
  672.     } else
  673.     baseWidth = baseHeight = 0;
  674.  
  675.  
  676.     if (tmp_win->hints.flags & PMaxSize) {
  677.         maxWidth = _min (Scr->MaxWindowWidth, tmp_win->hints.max_width);
  678.         maxHeight = _min (Scr->MaxWindowHeight, tmp_win->hints.max_height);
  679.     } else {
  680.         maxWidth = Scr->MaxWindowWidth;
  681.     maxHeight = Scr->MaxWindowHeight;
  682.     }
  683.  
  684.     if (tmp_win->hints.flags & PResizeInc) {
  685.         xinc = tmp_win->hints.width_inc;
  686.         yinc = tmp_win->hints.height_inc;
  687.     } else
  688.         xinc = yinc = 1;
  689.  
  690.     /*
  691.      * First, clamp to min and max values
  692.      */
  693.     if (dwidth < minWidth) dwidth = minWidth;
  694.     if (dheight < minHeight) dheight = minHeight;
  695.  
  696.     if (dwidth > maxWidth) dwidth = maxWidth;
  697.     if (dheight > maxHeight) dheight = maxHeight;
  698.  
  699.  
  700.     /*
  701.      * Second, fit to base + N * inc
  702.      */
  703.     dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
  704.     dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
  705.  
  706.  
  707.     /*
  708.      * Third, adjust for aspect ratio
  709.      */
  710. #define maxAspectX tmp_win->hints.max_aspect.x
  711. #define maxAspectY tmp_win->hints.max_aspect.y
  712. #define minAspectX tmp_win->hints.min_aspect.x
  713. #define minAspectY tmp_win->hints.min_aspect.y
  714.     /*
  715.      * The math looks like this:
  716.      *
  717.      * minAspectX    dwidth     maxAspectX
  718.      * ---------- <= ------- <= ----------
  719.      * minAspectY    dheight    maxAspectY
  720.      *
  721.      * If that is multiplied out, then the width and height are
  722.      * invalid in the following situations:
  723.      *
  724.      * minAspectX * dheight > minAspectY * dwidth
  725.      * maxAspectX * dheight < maxAspectY * dwidth
  726.      * 
  727.      */
  728.     
  729.     if (tmp_win->hints.flags & PAspect)
  730.     {
  731.         if (minAspectX * dheight > minAspectY * dwidth)
  732.         {
  733.             delta = makemult(minAspectX * dheight / minAspectY - dwidth,
  734.                              xinc);
  735.             if (dwidth + delta <= maxWidth) dwidth += delta;
  736.             else
  737.             {
  738.                 delta = makemult(dheight - dwidth*minAspectY/minAspectX,
  739.                                  yinc);
  740.                 if (dheight - delta >= minHeight) dheight -= delta;
  741.             }
  742.         }
  743.  
  744.         if (maxAspectX * dheight < maxAspectY * dwidth)
  745.         {
  746.             delta = makemult(dwidth * maxAspectY / maxAspectX - dheight,
  747.                              yinc);
  748.             if (dheight + delta <= maxHeight) dheight += delta;
  749.             else
  750.             {
  751.                 delta = makemult(dwidth - maxAspectX*dheight/maxAspectY,
  752.                                  xinc);
  753.                 if (dwidth - delta >= minWidth) dwidth -= delta;
  754.             }
  755.         }
  756.     }
  757.  
  758.  
  759.     /*
  760.      * Fourth, account for border width and title height
  761.      */
  762.     *widthp = dwidth;
  763.     *heightp = dheight + tmp_win->title_height;
  764. }
  765.  
  766.  
  767. /***********************************************************************
  768.  *
  769.  *  Procedure:
  770.  *      SetupWindow - set window sizes, this was called from either
  771.  *              AddWindow, EndResize, or HandleConfigureNotify.
  772.  *
  773.  *  Inputs:
  774.  *      tmp_win - the TwmWindow pointer
  775.  *      x       - the x coordinate of the upper-left outer corner of the frame
  776.  *      y       - the y coordinate of the upper-left outer corner of the frame
  777.  *      w       - the width of the frame window w/o border
  778.  *      h       - the height of the frame window w/o border
  779.  *      bw      - the border width of the frame window or -1 not to change
  780.  *
  781.  *  Special Considerations:
  782.  *      This routine will check to make sure the window is not completely
  783.  *      off the display, if it is, it'll bring some of it back on.
  784.  *
  785.  *      The tmp_win->frame_XXX variables should NOT be updated with the
  786.  *      values of x,y,w,h prior to calling this routine, since the new
  787.  *      values are compared against the old to see whether a synthetic
  788.  *      ConfigureNotify event should be sent.  (It should be sent if the
  789.  *      window was moved but not resized.)
  790.  *
  791.  ***********************************************************************
  792.  */
  793.  
  794. void SetupWindow (tmp_win, x, y, w, h, bw)
  795.     TwmWindow *tmp_win;
  796.     int x, y, w, h, bw;
  797. {
  798.     SetupFrame (tmp_win, x, y, w, h, bw, False);
  799. }
  800.  
  801. void SetupFrame (tmp_win, x, y, w, h, bw, sendEvent)
  802.     TwmWindow *tmp_win;
  803.     int x, y, w, h, bw;
  804.     Bool sendEvent;            /* whether or not to force a send */
  805. {
  806.     XEvent client_event;
  807.     XWindowChanges frame_wc, xwc;
  808.     unsigned long frame_mask, xwcm;
  809.     int title_width, title_height;
  810.     int reShape;
  811.  
  812. #ifdef DEBUG
  813.     fprintf (stderr, "SetupWindow: x=%d, y=%d, w=%d, h=%d, bw=%d\n",
  814.          x, y, w, h, bw);
  815. #endif
  816.  
  817.     if (x >= Scr->MyDisplayWidth)
  818.       x = Scr->MyDisplayWidth - 16;    /* one "average" cursor width */
  819.     if (y >= Scr->MyDisplayHeight)
  820.       y = Scr->MyDisplayHeight - 16;    /* one "average" cursor width */
  821.     if (bw < 0)
  822.       bw = tmp_win->frame_bw;        /* -1 means current frame width */
  823.  
  824.     if (tmp_win->iconmgr) {
  825.     tmp_win->iconmgrp->width = w;
  826.         h = tmp_win->iconmgrp->height + tmp_win->title_height;
  827.     }
  828.  
  829.     /*
  830.      * According to the July 27, 1988 ICCCM draft, we should send a
  831.      * "synthetic" ConfigureNotify event to the client if the window
  832.      * was moved but not resized.
  833.      */
  834.     if (((x != tmp_win->frame_x || y != tmp_win->frame_y) &&
  835.      (w == tmp_win->frame_width && h == tmp_win->frame_height)) ||
  836.     (bw != tmp_win->frame_bw))
  837.       sendEvent = TRUE;
  838.  
  839.     xwcm = CWWidth;
  840.     title_width = xwc.width = w;
  841.     title_height = Scr->TitleHeight + bw;
  842.  
  843.     ComputeWindowTitleOffsets (tmp_win, xwc.width, True);
  844.  
  845.     reShape = (tmp_win->wShaped ? TRUE : FALSE);
  846.     if (tmp_win->squeeze_info)        /* check for title shaping */
  847.     {
  848.     title_width = tmp_win->rightx + Scr->TBInfo.rightoff;
  849.     if (title_width < xwc.width)
  850.     {
  851.         xwc.width = title_width;
  852.         if (tmp_win->frame_height != h ||
  853.             tmp_win->frame_width != w ||
  854.         tmp_win->frame_bw != bw ||
  855.             title_width != tmp_win->title_width)
  856.             reShape = TRUE;
  857.     }
  858.     else
  859.     {
  860.         if (!tmp_win->wShaped) reShape = TRUE;
  861.         title_width = xwc.width;
  862.     }
  863.     }
  864.  
  865.     tmp_win->title_width = title_width;
  866.     if (tmp_win->title_height) tmp_win->title_height = title_height;
  867.  
  868.     if (tmp_win->title_w) {
  869.     if (bw != tmp_win->frame_bw) {
  870.         xwc.border_width = bw;
  871.         tmp_win->title_x = xwc.x = -bw;
  872.         tmp_win->title_y = xwc.y = -bw;
  873.         xwcm |= (CWX | CWY | CWBorderWidth);
  874.     }
  875.     
  876.     XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc);
  877.     }
  878.  
  879.     tmp_win->attr.width = w;
  880.     tmp_win->attr.height = h - tmp_win->title_height;
  881.  
  882.     XMoveResizeWindow (dpy, tmp_win->w, 0, tmp_win->title_height,
  883.                w, h - tmp_win->title_height);
  884.  
  885.     /* 
  886.      * fix up frame and assign size/location values in tmp_win
  887.      */
  888.     frame_mask = 0;
  889.     if (bw != tmp_win->frame_bw) {
  890.     frame_wc.border_width = tmp_win->frame_bw = bw;
  891.     frame_mask |= CWBorderWidth;
  892.     }
  893.     frame_wc.x = tmp_win->frame_x = x;
  894.     frame_wc.y = tmp_win->frame_y = y;
  895.     frame_wc.width = tmp_win->frame_width = w;
  896.     frame_wc.height = tmp_win->frame_height = h;
  897.     frame_mask |= (CWX | CWY | CWWidth | CWHeight);
  898.     XConfigureWindow (dpy, tmp_win->frame, frame_mask, &frame_wc);
  899.  
  900.     /*
  901.      * fix up highlight window
  902.      */
  903.     if (tmp_win->title_height && tmp_win->hilite_w)
  904.     {
  905.     xwc.width = (tmp_win->rightx - tmp_win->highlightx);
  906.     if (Scr->TBInfo.nright > 0) xwc.width -= Scr->TitlePadding;
  907.         if (xwc.width <= 0) {
  908.             xwc.x = Scr->MyDisplayWidth;    /* move offscreen */
  909.             xwc.width = 1;
  910.         } else {
  911.             xwc.x = tmp_win->highlightx;
  912.         }
  913.  
  914.         xwcm = CWX | CWWidth;
  915.         XConfigureWindow(dpy, tmp_win->hilite_w, xwcm, &xwc);
  916.     }
  917.  
  918.     if (HasShape && reShape) {
  919.     SetFrameShape (tmp_win);
  920.     }
  921.  
  922.     if (sendEvent)
  923.     {
  924.         client_event.type = ConfigureNotify;
  925.         client_event.xconfigure.display = dpy;
  926.         client_event.xconfigure.event = tmp_win->w;
  927.         client_event.xconfigure.window = tmp_win->w;
  928.         client_event.xconfigure.x = (x + tmp_win->frame_bw - tmp_win->old_bw);
  929.         client_event.xconfigure.y = (y + tmp_win->frame_bw +
  930.                      tmp_win->title_height - tmp_win->old_bw);
  931.         client_event.xconfigure.width = tmp_win->frame_width;
  932.         client_event.xconfigure.height = tmp_win->frame_height -
  933.                 tmp_win->title_height;
  934.         client_event.xconfigure.border_width = tmp_win->old_bw;
  935.         /* Real ConfigureNotify events say we're above title window, so ... */
  936.     /* what if we don't have a title ????? */
  937.         client_event.xconfigure.above = tmp_win->frame;
  938.         client_event.xconfigure.override_redirect = False;
  939.         XSendEvent(dpy, tmp_win->w, False, StructureNotifyMask, &client_event);
  940.     }
  941. }
  942.  
  943.  
  944. /**********************************************************************
  945.  *  Rutgers mod #1   - rocky.
  946.  *  Procedure:
  947.  *         fullzoom - zooms window to full height of screen or
  948.  *                    to full height and width of screen. (Toggles
  949.  *                    so that it can undo the zoom - even when switching
  950.  *                    between fullzoom and vertical zoom.)
  951.  *
  952.  *  Inputs:
  953.  *         tmp_win - the TwmWindow pointer
  954.  *
  955.  *
  956.  **********************************************************************
  957.  */
  958.  
  959. void
  960. fullzoom(tmp_win,flag)
  961. TwmWindow *tmp_win;
  962. int flag;
  963. {
  964.     Window      junkRoot;
  965.     unsigned int junkbw, junkDepth;
  966.     int basex, basey;
  967.     int frame_bw_times_2;
  968.  
  969.     XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
  970.             &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, &junkbw,
  971.             &junkDepth);
  972.  
  973.     basex = 0;
  974.     basey = 0;
  975.  
  976.         if (tmp_win->zoomed == flag)
  977.         {
  978.             dragHeight = tmp_win->save_frame_height;
  979.             dragWidth = tmp_win->save_frame_width;
  980.             dragx = tmp_win->save_frame_x;
  981.             dragy = tmp_win->save_frame_y;
  982.             tmp_win->zoomed = ZOOM_NONE;
  983.         }
  984.         else
  985.         {
  986.                 if (tmp_win->zoomed == ZOOM_NONE)
  987.                 {
  988.                         tmp_win->save_frame_x = dragx;
  989.                         tmp_win->save_frame_y = dragy;
  990.                         tmp_win->save_frame_width = dragWidth;
  991.                         tmp_win->save_frame_height = dragHeight;
  992.                         tmp_win->zoomed = flag;
  993.                  }
  994.                   else
  995.                             tmp_win->zoomed = flag;
  996.  
  997.  
  998.     frame_bw_times_2 = 2*tmp_win->frame_bw;
  999.  
  1000.         switch (flag)
  1001.         {
  1002.         case ZOOM_NONE:
  1003.             break;
  1004.         case F_ZOOM:
  1005.             dragHeight = Scr->MyDisplayHeight - frame_bw_times_2;
  1006.             dragy=basey;
  1007.             break;
  1008.         case F_HORIZOOM:
  1009.             dragx = basex;
  1010.             dragWidth = Scr->MyDisplayWidth - frame_bw_times_2;
  1011.             break;
  1012.         case F_FULLZOOM:
  1013.             dragx = basex;
  1014.             dragy = basey;
  1015.             dragHeight = Scr->MyDisplayHeight - frame_bw_times_2;
  1016.             dragWidth = Scr->MyDisplayWidth - frame_bw_times_2;
  1017.             break;
  1018.         case F_LEFTZOOM:
  1019.             dragx = basex;
  1020.             dragy = basey;
  1021.             dragHeight = Scr->MyDisplayHeight - frame_bw_times_2;
  1022.             dragWidth = Scr->MyDisplayWidth/2 - frame_bw_times_2;
  1023.             break;
  1024.         case F_RIGHTZOOM:
  1025.             dragx = basex + Scr->MyDisplayWidth/2;
  1026.             dragy = basey;
  1027.             dragHeight = Scr->MyDisplayHeight - frame_bw_times_2;
  1028.             dragWidth = Scr->MyDisplayWidth/2 - frame_bw_times_2;
  1029.             break;
  1030.         case F_TOPZOOM:
  1031.             dragx = basex;
  1032.             dragy = basey;
  1033.             dragHeight = Scr->MyDisplayHeight/2 - frame_bw_times_2;
  1034.             dragWidth = Scr->MyDisplayWidth - frame_bw_times_2;
  1035.             break;
  1036.         case F_BOTTOMZOOM:
  1037.             dragx = basex;
  1038.             dragy = basey + Scr->MyDisplayHeight/2;
  1039.             dragHeight = Scr->MyDisplayHeight/2 - frame_bw_times_2;
  1040.             dragWidth = Scr->MyDisplayWidth - frame_bw_times_2;
  1041.             break;
  1042.          }
  1043.       }
  1044.  
  1045.     if (!Scr->NoRaiseResize)
  1046.         XRaiseWindow(dpy, tmp_win->frame);
  1047.  
  1048.     ConstrainSize(tmp_win, &dragWidth, &dragHeight);
  1049.  
  1050.     SetupWindow (tmp_win, dragx , dragy , dragWidth, dragHeight, -1);
  1051.     XUngrabPointer (dpy, CurrentTime);
  1052.     XUngrabServer (dpy);
  1053. }
  1054.  
  1055. SetFrameShape (tmp)
  1056.     TwmWindow *tmp;
  1057. {
  1058.     /*
  1059.      * see if the titlebar needs to move
  1060.      */
  1061.     if (tmp->title_w) {
  1062.     int oldx = tmp->title_x, oldy = tmp->title_y;
  1063.     ComputeTitleLocation (tmp);
  1064.     if (oldx != tmp->title_x || oldy != tmp->title_y)
  1065.       XMoveWindow (dpy, tmp->title_w, tmp->title_x, tmp->title_y);
  1066.     }
  1067.  
  1068.     /*
  1069.      * The frame consists of the shape of the contents window offset by
  1070.      * title_height or'ed with the shape of title_w (which is always
  1071.      * rectangular).
  1072.      */
  1073.     if (tmp->wShaped) {
  1074.     /*
  1075.      * need to do general case
  1076.      */
  1077.     XShapeCombineShape (dpy, tmp->frame, ShapeBounding,
  1078.                 0, tmp->title_height, tmp->w,
  1079.                 ShapeBounding, ShapeSet);
  1080.     if (tmp->title_w) {
  1081.         XShapeCombineShape (dpy, tmp->frame, ShapeBounding,
  1082.                 tmp->title_x + tmp->frame_bw,
  1083.                 tmp->title_y + tmp->frame_bw,
  1084.                 tmp->title_w, ShapeBounding,
  1085.                 ShapeUnion);
  1086.     }
  1087.     } else {
  1088.     /*
  1089.      * can optimize rectangular contents window
  1090.      */
  1091.     if (tmp->squeeze_info) {
  1092.         XRectangle  newBounding[2];
  1093.         XRectangle  newClip[2];
  1094.         int fbw2 = 2 * tmp->frame_bw;
  1095.  
  1096.         /*
  1097.          * Build the border clipping rectangles; one around title, one
  1098.          * around window.  The title_[xy] field already have had frame_bw
  1099.          * subtracted off them so that they line up properly in the frame.
  1100.          *
  1101.          * The frame_width and frame_height do *not* include borders.
  1102.          */
  1103.         /* border */
  1104.         newBounding[0].x = tmp->title_x;
  1105.         newBounding[0].y = tmp->title_y;
  1106.         newBounding[0].width = tmp->title_width + fbw2;
  1107.         newBounding[0].height = tmp->title_height;
  1108.         newBounding[1].x = -tmp->frame_bw;
  1109.         newBounding[1].y = Scr->TitleHeight;
  1110.         newBounding[1].width = tmp->attr.width + fbw2;
  1111.         newBounding[1].height = tmp->attr.height + fbw2;
  1112.         XShapeCombineRectangles (dpy, tmp->frame, ShapeBounding, 0, 0,
  1113.                      newBounding, 2, ShapeSet, YXBanded);
  1114.         /* insides */
  1115.         newClip[0].x = tmp->title_x + tmp->frame_bw;
  1116.         newClip[0].y = 0;
  1117.         newClip[0].width = tmp->title_width;
  1118.         newClip[0].height = Scr->TitleHeight;
  1119.         newClip[1].x = 0;
  1120.         newClip[1].y = tmp->title_height;
  1121.         newClip[1].width = tmp->attr.width;
  1122.         newClip[1].height = tmp->attr.height;
  1123.         XShapeCombineRectangles (dpy, tmp->frame, ShapeClip, 0, 0,
  1124.                      newClip, 2, ShapeSet, YXBanded);
  1125.     } else {
  1126.         (void) XShapeCombineMask (dpy, tmp->frame, ShapeBounding, 0, 0,
  1127.                        None, ShapeSet);
  1128.         (void) XShapeCombineMask (dpy, tmp->frame, ShapeClip, 0, 0,
  1129.                       None, ShapeSet);
  1130.     }
  1131.     }
  1132. }
  1133.  
  1134. /*
  1135.  * Squeezed Title:
  1136.  * 
  1137.  *                         tmp->title_x
  1138.  *                   0     |
  1139.  *  tmp->title_y   ........+--------------+.........  -+,- tmp->frame_bw
  1140.  *             0   : ......| +----------+ |....... :  -++
  1141.  *                 : :     | |          | |      : :   ||-Scr->TitleHeight
  1142.  *                 : :     | |          | |      : :   ||
  1143.  *                 +-------+ +----------+ +--------+  -+|-tmp->title_height
  1144.  *                 | +---------------------------+ |  --+
  1145.  *                 | |                           | |
  1146.  *                 | |                           | |
  1147.  *                 | |                           | |
  1148.  *                 | |                           | |
  1149.  *                 | |                           | |
  1150.  *                 | +---------------------------+ |
  1151.  *                 +-------------------------------+
  1152.  * 
  1153.  * 
  1154.  * Unsqueezed Title:
  1155.  * 
  1156.  *                 tmp->title_x
  1157.  *                 | 0
  1158.  *  tmp->title_y   +-------------------------------+  -+,tmp->frame_bw
  1159.  *             0   | +---------------------------+ |  -+'
  1160.  *                 | |                           | |   |-Scr->TitleHeight
  1161.  *                 | |                           | |   |
  1162.  *                 + +---------------------------+ +  -+
  1163.  *                 |-+---------------------------+-|
  1164.  *                 | |                           | |
  1165.  *                 | |                           | |
  1166.  *                 | |                           | |
  1167.  *                 | |                           | |
  1168.  *                 | |                           | |
  1169.  *                 | +---------------------------+ |
  1170.  *                 +-------------------------------+
  1171.  * 
  1172.  * 
  1173.  * 
  1174.  * Dimensions and Positions:
  1175.  * 
  1176.  *     frame orgin                 (0, 0)
  1177.  *     frame upper left border     (-tmp->frame_bw, -tmp->frame_bw)
  1178.  *     frame size w/o border       tmp->frame_width , tmp->frame_height
  1179.  *     frame/title border width    tmp->frame_bw
  1180.  *     extra title height w/o bdr  tmp->title_height = TitleHeight + frame_bw
  1181.  *     title window height         Scr->TitleHeight
  1182.  *     title origin w/o border     (tmp->title_x, tmp->title_y)
  1183.  *     client origin               (0, Scr->TitleHeight + tmp->frame_bw)
  1184.  *     client size                 tmp->attr.width , tmp->attr.height
  1185.  * 
  1186.  * When shaping, need to remember that the width and height of rectangles
  1187.  * are really deltax and deltay to lower right handle corner, so they need
  1188.  * to have -1 subtracted from would normally be the actual extents.
  1189.  */
  1190.